package com.spzx.order.listener;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rabbitmq.client.Channel;
import com.spzx.common.rabbitmq.service.RabbitmqService;
import com.spzx.order.domain.OrderInfo;
import com.spzx.order.domain.OrderLog;
import com.spzx.order.service.IOrderInfoService;
import com.spzx.order.service.IOrderLogService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class SpzxOrderMqListener {
    @Resource
    IOrderInfoService orderInfoService;
    @Resource
    RabbitmqService rabbitmqService;
    @Resource
    IOrderLogService orderLogService;

    //支付成功 发送消息： 更新订单支付状态
    @RabbitListener(bindings = {
            @QueueBinding(
                    exchange = @Exchange(value="spzx.payment.exchange",
                            type = ExchangeTypes.TOPIC),
                    value = @Queue("spzx.order.payment.queue"),
                    key = "spzx.pay.success.msg"
            )
    })
    public void updateOrderStatus(Message message , Map<String,String> map , Channel channel) throws IOException {
        try {
            String orderNo = map.get("orderNo");
            String type = map.get("type");
            orderInfoService.update(Wrappers.lambdaUpdate(OrderInfo.class)
                    .eq(OrderInfo::getOrderNo , orderNo)
                    .set(OrderInfo::getOrderStatus , type.equals("1")?1:-1)//1表示支付成功  -1表示取消
                    //.eq(OrderInfo::getOrderStatus , 0) //更新待付款状态的订单
            );
            //更新订单日志状态
//            orderLogService.update();
            orderLogService.updateAsync(orderNo,type);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            if(message.getMessageProperties().isRedelivered()){
                //日志记录丢弃的消息
                log.error("spzx-cart删除购物车选中购物项失败,消息内容:{}" , JSON.toJSONString(map));
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }
    }


    /*
        消费者服务 需要配置手动ack 和能者多劳
     */
    //延迟关单消费者： 监听延迟队列/死信队列
    @RabbitListener(queues = {"spzx.close.order.dead.queue"})
    public void closeOrder(Message message , String orderNo , Channel channel) throws IOException {

        try {
            //1、消费消息的业务
            //修改订单的状态为 关闭状态即可！！！！！  只有待支付状态的订单 才可以被关闭
            boolean flag = orderInfoService.update(Wrappers.lambdaUpdate(OrderInfo.class)
                    .eq(OrderInfo::getOrderNo, orderNo)
                    .eq(OrderInfo::getOrderStatus, 0)
                    .set(OrderInfo::getOrderStatus, -1));

            // 关单成功 发送消息 释放锁定的库存！！！
            if(flag){
                //关单成功：此时需要释放锁定的库存（spzx-product）
                rabbitmqService.sendMsg("spzx.product.stock.exchange",
                        "product.stock.release.msg" , orderNo );
            }
            //2、正常执行 手动ack  mq删除消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            //3、如果出现异常 尝试重试消费 消费失败丢弃消息
            if(message.getMessageProperties().isRedelivered()){
                //再次消费失败
                log.error("closeOrder-消费消息失败,丢弃消息,消息内容：{}" , orderNo);
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else{
                //第一次失败
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }


    }



//    @Resource
//    IOrderLogService orderLogService;
    //保存订单创建成功的日志
    @RabbitListener(bindings = {
            @QueueBinding(
                    exchange = @Exchange(value="spzx.order.submmit.exchange",
                            type = ExchangeTypes.TOPIC),
                    value = @Queue("spzx.log.order.submit.queue"), //购物车服务接收提交订单消息的 队列
                    key = "spzx.order.submit.msg"
            )
    })
    public void clearCart(Message message , Map<String,Object> map , Channel channel) throws IOException {
        try {
            //删除购物车中选中的购物项
//            Long userId = Long.parseLong(map.get("userId").toString());

            Long orderId = (Long) map.get("orderId");
            Integer orderStatus = (Integer) map.get("orderStatus");
            OrderLog orderLog = new OrderLog();
            orderLog.setOrderId(orderId);
            orderLog.setProcessStatus(orderStatus.longValue());
            orderLog.setOperateUser("用户");
            orderLog.setNote("订单创建成功");
            orderLogService.save(orderLog);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            if(message.getMessageProperties().isRedelivered()){
                //日志记录丢弃的消息
                log.error("spzx-cart删除购物车选中购物项失败,消息内容:{}" , JSON.toJSONString(map));
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }
    }


}
